local socket = require "socket"
local skynet = require "skynet"
local crypt = require "crypt"
local sysinfo=require "sysinfo"
require "skynet.manager"	
local command = {}
local mainserver ,myaddr
local time_befor
local keyindex = 1
local localkey = "123"
local descmp   = "123"
local deskey   = "123"
local authed   = false
local gatedeskey  = "89231#42"
local gateextern = {}
local sendIndex = 1
local recvIndex = 1
local diffSec   = 5
local authed    = false
local sendinfo  = {}
local _ip = ""
local _port = 0
local dstfd = 0

local randkey = {[1] = "dssferw1",[2] =  "34eghjhg",  [3] =  "34erwfgd", [4] = "2#433423",
                 [5] = "34521313",[6] =  "dfssffff",  [7] =  "erweerwe", [8] = "Fdfdfere",
                 [9] = "12342rew",[10] = "bdfdsere",  [11] = "evfgdrrt",[12] = "erwer331",
                 [13] ="223edfbf",[14] = "erwerfdf",  [15] = "45rte45$",[16] = "dfserdfe"}
local CMD = {}
CMD.Main_ClientToSvr_NetGate               = 200
CMD.Main_SvrToClient_NetGate               = 201
CMD.Sub_ClientToSvr_NetGate_Base           = 1000
CMD.Sub_SvrToClient_NetGate_Base           = 2000

CMD.Sub_ClientToGate_Hand                  = CMD.Sub_ClientToSvr_NetGate_Base + 1
CMD.Sub_ClientToGate_Auth                  = CMD.Sub_ClientToSvr_NetGate_Base + 2
CMD.Sub_ClientToGate_ConnectGameSer        = CMD.Sub_ClientToSvr_NetGate_Base + 3
CMD.Sub_ClientToGate_CheckNet              = CMD.Sub_ClientToSvr_NetGate_Base + 4
CMD.Sub_ClientToGate_GetNetInfor           = CMD.Sub_ClientToSvr_NetGate_Base + 5

CMD.Sub_GateToClient_Hand                  = CMD.Sub_SvrToClient_NetGate_Base + 1
CMD.Sub_GateToClient_Auth                  = CMD.Sub_SvrToClient_NetGate_Base + 2
CMD.Sub_GateToClient_ConnectGameSer        = CMD.Sub_SvrToClient_NetGate_Base + 3
CMD.Sub_GateToClient_CheckNet              = CMD.Sub_SvrToClient_NetGate_Base + 4

CMD.Main_ClientAndGameSvr_UserModle         = 300
CMD.Main_ClientAndGameSvr_TableModle        = 303      --好友场主命令

CMD.Main_Max                                = 500
CMD.sub_Max                                 = 3000      



local function send_package(fd,pack)
	local package = string.pack(">s2", pack)
	socket.write(fd, package)
end


function head_msg(msg,fd)
     local keyindex,clientkey=string.unpack("<I2c8", msg,5) 
     local randStr = string.pack("c8c8",clientkey,randkey[keyindex])
     local shakey = crypt.hmac_sha1(clientkey, randStr)
     deskey = string.sub(shakey, 1, 8)
     local dststr = string.pack("c8c8c8c8",clientkey,clientkey,clientkey,clientkey)
     descmp = crypt.desencode(deskey, dststr)
     send_package(fd,string.pack(">I2>I2<c40", CMD.Main_ClientToSvr_NetGate, CMD.Sub_ClientToGate_Auth,descmp))
end

function auth_msg(msg,fd)
     local auth_re=string.unpack("<I2", msg,5)
     if auth_re==20 then
        authed = true
        time_befor=sysinfo.gettime()
        send_package(fd,string.pack(">I2>I2", CMD.Main_ClientToSvr_NetGate, CMD.Sub_ClientToGate_GetNetInfor))
     end
 
end

function gate_msg(msg,len_,fd)
    local tem_len=len_-4
    local time_out_=(sysinfo.gettime()-time_befor)/2000
    local agent_num=string.unpack("c"..tem_len, msg,5)
    sendinfo = {addr=myaddr,num=agent_num,time_out=time_out_}
end

function sendmsg()
    while true do
        if authed == true then
            skynet.send(mainserver,"lua","data",sendinfo)
            time_befor=sysinfo.gettime()
            send_package(dstfd,string.pack(">I2>I2", CMD.Main_ClientToSvr_NetGate, CMD.Sub_ClientToGate_GetNetInfor))
            sendinfo = {addr=myaddr,num=0,time_out=0}
        end
        skynet.sleep(500)
     end
end

function revmsg()
    while true do
        if dstfd == 0 or not dstfd then
            dstfd  = socket.open(_ip, _port)
            if not dstfd then
                authed = false
                skynet.error("can't connect to "..myaddr)
                skynet.sleep(500)
            else
                skynet.error("connect to "..myaddr)
                send_package(dstfd, string.pack(">I2>I2", CMD.Main_ClientToSvr_NetGate, CMD.Sub_ClientToGate_Hand))
            end
        else 
            local readsize=socket.read(dstfd,2)
            if not read_size then
                local len_ = string.unpack(">I2",readsize)
                local msg=socket.read(dstfd,len_)
                local mcmd,scmd= string.unpack(">I2>I2", msg,1) 
                if mcmd==CMD.Main_SvrToClient_NetGate then
                    if scmd==CMD.Sub_GateToClient_Hand then
                        head_msg(msg,dstfd)
                        skynet.error("head_msg ...".._ip.._port)
                    end 
                    if scmd==CMD.Sub_GateToClient_Auth then
                        auth_msg(msg,dstfd)
                        skynet.error("auth_msg ...".._ip.._port)
                    end
                    if scmd==CMD.Sub_ClientToGate_GetNetInfor then
                        gate_msg(msg,len_,dstfd)  
                    end
                end
            else
                skynet.error("find dstfd disconnect "..myaddr)
            end
        end
     end
end

function command.start(conf)
    _ip = conf.ip
    _port = conf.port
    mainserver=conf.mainserver 
    myaddr=_ip..":".._port
    sendinfo = {addr=myaddr,num=0,time_out=0}
    skynet.fork(revmsg) 
    skynet.fork(sendmsg) 
end

skynet.start(function()
    skynet.dispatch("lua", function(session, source, cmd, subcmd, ...)
        local f = assert(command[cmd])
        skynet.ret(skynet.pack(f(subcmd, ...)))
	end)
    skynet.error("getgateinfo server start...")
    math.randomseed(os.time())
end)
